import os
import sys
import matplotlib.pyplot as plt
import keyboard
import PySpin

global continue_recording
continue_recording = True

def handle_close(evt):
    global continue_recording
    continue_recording = False

def acquire_and_display_images(cam, nodemap, nodemap_tldevice):
    global continue_recording
    #stream node map 数据流点映射
    sNodemap = cam.GetTLStreamNodeMap()

    node_bufferhandling_mode = PySpin.CEnumerationPtr(sNodemap.GetNode('StreamBufferHandlingMode'))
    if not PySpin.IsAvailable(node_bufferhandling_mode) or not PySpin.IsWritable(node_bufferhandling_mode):
        print('数据路缓存处理模式不能设置，丢弃...')
        return False

    node_newestonly = node_bufferhandling_mode.GetEntryByName('NewestOnly')
    if not PySpin.IsAvailable(node_newestonly) or not PySpin.IsReadable(node_newestonly):
        print('数据路缓存处理模式不能设置，丢弃...')
        return False

    node_newestonly_mode = node_newestonly.GetValue()
    node_bufferhandling_mode.SetIntValue(node_newestonly_mode)
    print('***** 图像获取 *****\n')
    try:
        node_acquisition_mode = PySpin.CEnumerationPtr(nodemap.GetNode('AcquisitionMode'))
        if not PySpin.IsAvailable(node_acquisition_mode) or not PySpin.IsWritable(node_acquisition_mode):
            print('无法设置获取模式为连续型号,舍弃')
            return False

        node_acquisition_mode_continuous = node_acquisition_mode.GetEntryByName('Continuous')
        if not PySpin.IsAvailable(node_acquisition_mode_continuous) or not PySpin.IsReadable(node_acquisition_mode_continuous):
            print('无法设置获取模式为连续型号,舍弃')
            return False

        acquistion_mode_continuous = node_acquisition_mode_continuous.GetValue()
        node_acquisition_mode.SetIntValue(acquistion_mode_continuous)
        print('接收模式设置完毕')
        cam.BeginAcquisition()
        print('获取图像')
        fig = plt.figure(1)
        fig.canvas.mpl_connect('close_event', handle_close)
        while(continue_recording):
            try:
                image_result = cam.GetNextImage(100)
                if image_result.IsIncomplete():
                    print('接收的图像不完整，图片的状态为%d...' %image_result.GetImageStatus())
                else:
                    #将图片转化为numpy数列
                    image_data = image_result.GetNDArray()
                    plt.imshow(image_data, cmap='gray')
                    plt.pause(0.01)
                    plt.clf()

                    if keyboard.is_pressed('ENTER'):
                        print('Program is closing')
                        plt.close('all')
                        input('完毕，按Enter退出')
                        continue_recording = False

                image_result.Release()

            except PySpin.SpinnakerException as ex:
                print('Error: %s' % ex)
                return False



    except PySpin.SpinnakerException as ex:
        print('Error: %s' %ex)
        return False

    return True




def run_single_camera(cam):
    try:

        result = True
        nodemap_tldevice = cam.GetTLDeviceNodeMap()

        cam.Init()

        nodemap = cam.GetNodeMap()

        result &= acquire_and_display_images(cam, nodemap, nodemap_tldevice)

        cam.DeInit()
    except:
        result = False
    return result

def main():
    result = True
    system = PySpin.System.GetInstance()
    version = system.GetLibraryVersion()
    print('Library version:%d.%d.%d.%d'%(version.major, version.minor,version.type,version.build))

    cam_list = system.GetCameras()
    num_cameras = cam_list.GetSize()

    if num_cameras == 0:
        cam_list.Clear()
        system.ReleaseInstance()

        print('没有检测到相机')
        return False

    for i,cam in enumerate(cam_list):
        print('正在运行%d号相机'%i)
        result &= run_single_camera(cam)
        print('%d号相机运行完毕' %i)

    del cam
    cam_list.Clear()
    system.ReleaseInstance()

    input('全部执行完毕，请输入Enter退出')
    return result

if __name__ == '__main__':
    if main():
        sys.exit(0)
    else:
        sys.exit(1)
